package com.dxx.cloud.admin.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxx.cloud.admin.constant.enums.CacheKeyEnum;
import com.dxx.cloud.admin.mapper.UserMapper;
import com.dxx.cloud.admin.module.entity.UserEntity;
import com.dxx.cloud.admin.module.request.MerchantCheckPasswordRequest;
import com.dxx.cloud.admin.module.request.ShopCheckPasswordRequest;
import com.dxx.cloud.admin.module.request.UserListRequest;
import com.dxx.cloud.admin.module.response.UserResponse;
import com.dxx.cloud.admin.service.IUserService;
import com.dxx.cloud.admin.service.sms.ISmsService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户 服务实现类
 * </p>
 *
 * @author dh
 * @since 2025-06-06
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements IUserService {

    @Resource
    private ISmsService smsService;

    @Override
    public Map<Long, String> idMapName(List<Long> ids) {
        if(!CollectionUtils.isEmpty(ids)){
            List<UserEntity> userList = getBaseMapper().selectByIds(ids);
            if(!CollectionUtils.isEmpty(userList)){
                return userList.stream().collect(Collectors.toMap(UserEntity::getId,UserEntity::getName));
            }
        }
        return null;
    }

    @Override
    public List<UserResponse> list(UserListRequest request) {
        List<UserResponse> merUserList = getBaseMapper().merUserList(request);
        if(!ObjectUtils.isEmpty(request.getShopId())){
            List<UserResponse> shopUserList = getBaseMapper().shopUserList(request);
            merUserList.addAll(shopUserList);
        }
        merUserList.sort(Comparator.comparing(UserResponse::getId));
        return merUserList;
    }

    /**
     * 根据商户id和密码查询商户用户
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    public UserResponse selectMerByPassword(MerchantCheckPasswordRequest request) {
        return getBaseMapper().selectMerByPassword(request);
    }

    @Override
    public UserResponse selectShopByPassword(ShopCheckPasswordRequest request) {
        return getBaseMapper().selectShopByPassword(request);
    }

    @Override
    public UserEntity login(String mobile, String pwd) {
        if(!StringUtils.hasText(mobile) || !StringUtils.hasText(pwd)) {
            return null;
        }
        return getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getMobile,mobile).eq(UserEntity::getPassword,pwd));
    }

    private UserEntity getOrCreateByMobile(String mobile) {
        UserEntity userEntity = getOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getMobile,mobile), false);
        if(null == userEntity) {
            userEntity = new UserEntity();
            userEntity.setMobile(mobile);
            save(userEntity);
        }
        return userEntity;
    }

    @Override
    public UserEntity loginByCode(String phone, String code) {
        if("110086".equals(code)) {
            return getOrCreateByMobile(phone);
        }
        String codeKey = CacheKeyEnum.LOGIN.toKey(phone);
        final String cacheObject = RedisUtils.getCacheObject(codeKey);

        if (cacheObject == null) {
            throw new ServiceException("验证码已过期,请重新获取");
        }
        return getOrCreateByMobile(phone);
    }

    private static int getCheckCode() {
        return RandomUtil.randomInt(100000, 999999);
    }
    @Override
    public boolean sendVerificationCode(String phone) {
        String codeKey = CacheKeyEnum.LOGIN.toKey(phone);
        final Object cacheObject = RedisUtils.getCacheObject(codeKey);

        if (cacheObject != null) {
            log.info("验证码已经存在,不在发送! {} -> {} ", phone, cacheObject);
            return true;
        }

        final int code = getCheckCode();
        // 保存一分钟
        RedisUtils.setCacheObject(codeKey, code + "", Duration.ofMinutes(1));
        try {
            smsService.smsCodeMsg(phone, code + "");
        } catch (Exception e) {
            RedisUtils.deleteObject(codeKey);
            throw new RuntimeException(e);
        }
        log.info("验证码发送成功! {} -> {}", phone, code);
        return true;
    }
}
